package com.xh.web.service.impl;


import com.xh.web.constant.Constants;
import com.xh.web.domain.*;
import com.xh.web.domain.vo.ContentVo;
import com.xh.web.domain.vo.TableVo;
import com.xh.web.mapper.*;
import com.xh.web.service.IDTableService;
import com.xh.web.util.JsonUtil;
import com.xh.web.util.StringUtils;
import com.xh.web.util.velocity.VelocityInitializer;
import com.xh.web.util.velocity.VelocityUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.StringWriter;
import java.util.*;


/**
 * 表Service业务层处理
 *
 * @author dongxuefei
 * @date 2020-09-04
 */
@Service
@Transactional
public class DTableServiceImpl implements IDTableService {
    @Autowired(required = false)
    private DTableMapper dTableMapper;

    @Autowired(required = false)
    private DColumnMapper dColumnMapper;
    @Autowired(required = false)
    private DProjectMapper dProjectMapper;

    @Autowired(required = false)
    private DContentMapper dContentMapper;

    @Autowired(required = false)
    private DProjectHisMapper dProjectHisMapper;
    @Autowired(required = false)
    private DTableIndexMapper dTableIndexMapper;


    /**
     * 根据表id进行查询
     *
     * @param
     * @return
     */
    public DTable selectDTableById(String id) {
        return dTableMapper.selectDTableById(id);
    }


    /**
     * 查询首页表,根据条件模糊查询查询
     *
     * @param dTable
     * @return
     */
    @Override
    public List<DTable> selectDTableList(DTable dTable) {
        return dTableMapper.selectDTableList(dTable);
    }


    /**
     * 新增表
     *
     * @param dTable
     * @return
     */
    @Override
    public int insertDTable(DTable dTable) {

        DProject dProject = dProjectMapper.selectDProjectById(dTable.getProjectId());

        if (dProject == null) {
            return 0;
        }

        dProject.setTableNum(dProject.getTableNum() + 1);
        dTable.setColumnNum(0);

        dTable.setCreateBy("admin");
        dTable.setCreateDate(new Date());
        dTable.setUpdateBy("admin");
        dTable.setUpdateDate(new Date());
        dTable.setDelFlag("0");
        dTable.setCreateName("admin");
        dTable.setUpdateName("admin");
        dTable.setdSort(new Long(0));
        dProjectMapper.updateDProject(dProject);
        //保存历史
        DProjectHis dProjectHis=new DProjectHis();
        dProjectHis.setProjectId(dTable.getProjectId());
        dProjectHis.setOperationType("2");
        dProjectHis.setOperationDesc(("新增表:"+dTable.getTableCode()));
        dProjectHis.setCreateBy("admin");
        dProjectHis.setCreateName("admin");
        dProjectHis.setCreateDate(new Date());
        dProjectHis.setUpdateBy("admin");
        dProjectHis.setUpdateDate(new Date());
        dProjectHis.setDelFlag("0");
        dProjectHis.setTableCode(dTable.getTableCode());
        dProjectHis.setTableName(dTable.getTableName());
        dProjectHisMapper.insertDProjectHis(dProjectHis);
        return dTableMapper.insertDTable(dTable);
    }

    /**
     * 修改表
     *
     * @param dTable
     * @return
     */
    @Override
    public int updateDTable(DTable dTable) {
        if (dTable == null) {
            return 0;
        }
        dTable.setUpdateName("admin");
        dTable.setUpdateDate(new Date());
        dTable.setUpdateBy("admin");
        return dTableMapper.updateDTable(dTable);
    }


    /**
     * 批量删除
     *
     * @param ids 需要删除的ID
     * @return 结果
     */
    @Override
    public int deleteDTableByIds(String[] ids) {
        return dTableMapper.deleteDTableByIds(ids);
    }

    /**
     * 删除表
     *
     * @param id 表id
     * @return
     */
    @Override
    public int deleteDTableById(String id) {
        DTable dTable = dTableMapper.selectDTableById(id);
        DProject dProject = dProjectMapper.selectDProjectById(dTable.getProjectId());
        if (dProject == null) {
            return 0;
        }
        dProject.setTableNum(dProject.getTableNum() - 1);
        dProjectMapper.updateDProject(dProject);
        //保存历史
        DProjectHis dProjectHis=new DProjectHis();
        dProjectHis.setProjectId(dTable.getProjectId());
        dProjectHis.setOperationType("4");
        dProjectHis.setOperationDesc("删除表:"+dTable.getTableCode());
        dProjectHis.setCreateBy("admin");
        dProjectHis.setCreateName("admin");
        dProjectHis.setCreateDate(new Date());
        dProjectHis.setUpdateBy("admin");
        dProjectHis.setUpdateDate(new Date());
        dProjectHis.setDelFlag("0");
        dProjectHis.setTableCode(dTable.getTableCode());
        dProjectHis.setTableName(dTable.getTableName());
        dProjectHisMapper.insertDProjectHis(dProjectHis);
        dColumnMapper.deleteAllColumnByProjectId(dTable.getProjectId(),dTable.getTableCode());
        return dTableMapper.deleteDTableById(id);
    }

    /**
     * 根据表code进行查询
     *
     * @param
     * @return
     */
    public DTable selectDTableByCode(String tableCode, String projectId) {
        return dTableMapper.selectDTableByCode(tableCode, projectId);
    }
    @Override
    public int insertDTableListOfficial(List<DTable> tableList) {
        return dTableMapper.insertDTableListOfficial(tableList);
    }

    @Override
    public String[] selectTableIdsByProjectId(String projectId) {
        return dTableMapper.selectTableIdsByProjectId(projectId);
    }

    /**
     * 预览代码
     *
     * @param tableId 表编号
     * @return 预览数据列表
     */
    @Override
    public Map<String, String> previewCode(String tableId, String columnId) {
        Map<String, String> dataMap = new LinkedHashMap<>();
        // 查询表信息
       DTable dTable= dTableMapper.selectDTableById(tableId);
       DProject dProject=dProjectMapper.selectDProjectById(dTable.getProjectId());
       DTableIndex dTableIndex=new DTableIndex();
       dTableIndex.setProjectId(dTable.getProjectId());
       dTableIndex.setTableCode(dTable.getTableCode());
      List<DTableIndex>  tableIndexs=dTableIndexMapper.selectDTableIndexList(dTableIndex);

        DColumn dColumn=new DColumn();
        dColumn.setTableId(tableId);
        List<DColumn> columns= dColumnMapper.selectDColumnList(dColumn);
        VelocityInitializer.initVelocity();
        VelocityContext context = new VelocityContext();
        context.put("tableCode",dTable.getTableCode());
        context.put("tableName",dTable.getTableName());
        context.put("columnList",columns);
        context.put("indexList",tableIndexs);

        // 获取模板列表
        List<String> templates = VelocityUtils.getTemplateList("table_"+dProject.getDbType());
        for (String template : templates) {
            // 渲染模板
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
            tpl.merge(context, sw);
            dataMap.put(template, sw.toString());
        }
        return dataMap;
    }






    @Override
    public String getTableTree(String projectId, String contentId) {
        //获取目录
        List<ContentVo> contentslist = getContentsVo(projectId);
        //获取目录下面的表
        List<TableVo> tableList = getTablesVo(projectId);
        //目录
        List<ContentVo> categoriesList = new ArrayList<>();

        //最后返回的拼接内容
        Map<String, Object> mapJson = new HashMap<>();

        for (ContentVo category : contentslist) {
            // 如果为空的话  就是父目录了
            if (StringUtils.isEmpty(category.getParentId())) {
                categoriesList.add(category);
            }
        }
        // 为一级菜单设置子菜单，getChild是递归调用的
        List<Object> objects = new ArrayList<>();
        List<Object> objectsTemp = null;
        for (ContentVo category : categoriesList) {
            objectsTemp = new ArrayList<>();
            List<ContentVo> childe = getChilde(category.getId(), contentslist, tableList);
            //拼接目录跟菜单
            judgeJionMenu(tableList, objectsTemp, category, childe);
            //拼接菜单
            judgeJionChilde(tableList, category, childe);
            //需要拼接表的目录
            objects.add(category);
        }
        //获取没有挂在目录下面的表
        for (TableVo cate : tableList) {
            if (StringUtils.isEmpty(cate.getContentId())) {
                objects.add(cate);
            }
        }
        mapJson.put("children", objects);
        String toJSONString = JsonUtil.toJSONString(mapJson);
        return toJSONString;
    }
    //获取所有的表
    private List<TableVo> getTablesVo(String projectId) {
        DTable table = new DTable();
        table.setProjectId(projectId);
        List<DTable> tableList = dTableMapper.selectDTableList(table);
        List<TableVo> tableVoList = new ArrayList<>();
        TableVo tableVo = null;
        for (DTable cate : tableList) {
            tableVo = new TableVo();
            tableVo.setContentId(cate.getContentId());
            tableVo.setId(cate.getId());
            tableVo.setLabel(cate.getTableCode());
            tableVo.setTableCode(cate.getTableCode());
            tableVo.setTableName(cate.getTableName());
            tableVo.setType("table");
            tableVoList.add(tableVo);
        }
        return tableVoList;
    }

    //获取所有的目录
    private List<ContentVo> getContentsVo(String projectId) {
        DContent dContent = new DContent();
        dContent.setProjectId(projectId);
        List<DContent> contentslist = dContentMapper.selectDContentList(dContent);//获取该项目下的顶级目录
        List<ContentVo> contentVosList = new ArrayList<>();
        ContentVo contentVos = null;
        for (DContent category : contentslist) {
            contentVos = new ContentVo();
            contentVos.setId(category.getId());
            contentVos.setContentName(category.getContentName());
            contentVos.setLabel(category.getContentName());
            contentVos.setParentId(category.getParentId());
            contentVos.setType("content");
            contentVosList.add(contentVos);
        }
        return contentVosList;
    }

    /**
     * 递归查找子菜单
     *
     * @param id       当前菜单id
     * @param rootList 要查找的列表
     * @return
     */
    private List<ContentVo> getChilde(String id, List<ContentVo> rootList, List<TableVo> caTables) {
        //子菜单
        List<ContentVo> childList = new ArrayList<>();
        for (ContentVo category : rootList) {
            // 遍历所有节点，将父菜单id与传过来的id比较
            if (StringUtils.isNotEmpty(category.getParentId()) && category.getParentId().equals(id)) {
                childList.add(category);
            }
        }

        List<Object> objectsTemp = null;
        // 把子菜单的子菜单再循环一遍
        for (ContentVo category : childList) {
            objectsTemp = new ArrayList<>();
            //这是递归查询
            List<ContentVo> childe = getChilde(category.getId(), rootList, caTables);
            //拼接目录跟菜单
            judgeJionMenu(caTables, objectsTemp, category, childe);

            // 这种情况是下面没有目录了
            judgeJionChilde(caTables, category, childe);
        }
        // 递归退出条件
        if (childList.size() == 0) {
            return null;
        }

        return childList;
    }

    /**
     * 合并菜单跟目录
     *
     * @param caTables
     * @param objectsTemp
     * @param category
     * @param childe
     */
    private void judgeJionMenu(List<TableVo> caTables, List<Object> objectsTemp, ContentVo category, List<ContentVo> childe) {
        if (childe != null && childe.size() > 0) {
            //获取当前目录下面的所有菜单
            List<TableVo> caTableList = getMenuTable(category.getId(), caTables);
            if (caTableList != null) {
                for (TableVo cate : caTableList) {
                    objectsTemp.add(cate);
                }
            }
            for (ContentVo gory : childe) {
                objectsTemp.add(gory);
            }
            category.setChildren(objectsTemp);
        }
    }

    /**
     * 没有目录的情况下 拼接子菜单
     *
     * @param caTables
     * @param category
     * @param childe
     */
    private void judgeJionChilde(List<TableVo> caTables, ContentVo category, List<ContentVo> childe) {
        if (childe == null || childe.size() == 0) {
            category.setChildren(getMenuTable(category.getId(), caTables));
        }
    }

    /**
     * 获取目录下面的菜单信息
     *
     * @param id
     * @param caTables
     * @return
     */
    private static List<TableVo> getMenuTable(String id, List<TableVo> caTables) {
        List<TableVo> objects = new ArrayList<>();
        for (TableVo cate : caTables) {
            if (StringUtils.isNotEmpty(cate.getContentId()) && cate.getContentId().equals(id)) {
                objects.add(cate);
            }
        }
        if (objects == null || objects.size() == 0) {
            return null;
        }
        return objects;
    }
    //更新创建人信息
    public  int updateTableUser(DTable dTable){
        return dTableMapper.updateTableUser(dTable);
    }

    public List<DTable> getRelation(DTable dTable){
        return dTableMapper.getRelation(dTable);
    }
}
